package smedi.ismedi.mobile.bff.controller.quality;

import cn.hutool.core.collection.CollectionUtil;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.inmail.api.dto.request.ProcessTaskListRequest;
import com.smedi.ismedi.inmail.api.dto.response.ProcessTaskResponse;
import com.smedi.ismedi.inmail.api.feign.RemoteProcessFeignApi;
import com.smedi.ismedi.instrument.api.dto.request.hiddenDanger.QueryQualityHiddenDangerByOneRequest;
import com.smedi.ismedi.instrument.api.dto.request.hiddenDanger.QueryQualityHiddenDangerPageRequest;
import com.smedi.ismedi.instrument.api.dto.request.qualityCheck.*;
import com.smedi.ismedi.instrument.api.dto.response.PersonResponse;
import com.smedi.ismedi.instrument.api.dto.response.hiddenDanger.QualityHiddenDangerResponse;
import com.smedi.ismedi.instrument.api.dto.response.qualityCheck.QualityCheckDeatilResponse;
import com.smedi.ismedi.instrument.api.dto.response.qualityCheck.QualityCheckResponse;
import com.smedi.ismedi.instrument.api.dto.response.qualityCheck.ReplyQualityCheckResponse;
import com.smedi.ismedi.instrument.api.feign.RemoteQualityCheckFeignApi;
import com.smedi.ismedi.instrument.api.feign.RemoteQualityHiddenDangerFeignApi;
import com.smedi.ismedi.safetycheck.dto.request.danger.QueryHiddenDangerByCheckRequest;
import com.smedi.ismedi.safetycheck.dto.response.danger.HiddenDangerDetailResponse;
import com.smedi.ismedi.safetycheck.dto.response.danger.HiddenDangerResponse;
import com.smedi.ismedi.safetycheck.feign.RemoteHiddenDangerFeignApi;
import com.smedi.ismedi.web.starter.common.PaginationData;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import smedi.ismedi.mobile.bff.converter.Converter;
import smedi.ismedi.mobile.bff.dto.HiddenDangerOperateDetailResponse;
import smedi.ismedi.mobile.bff.dto.HiddenDangerOperateResponse;
import smedi.ismedi.mobile.bff.dto.quality.*;
import smedi.ismedi.mobile.bff.infrastructure.constant.ConstantField;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author yangzhenzhou
 * @date 2022/10/24
 */
@FeignClient(name = "ismedi-quality")
@Api(value = "质量检查接口", tags = {"质量检查接口"})
@RequestMapping(value = "/mobilebff/v1/qualityCheck")
@RestController
@AllArgsConstructor
public class QualityCheckController {
    private final RemoteQualityCheckFeignApi remoteQualityCheckFeignApi;
    private final RemoteHiddenDangerFeignApi remoteHiddenDangerFeignApi;
    private final RemoteQualityHiddenDangerFeignApi remoteQualityHiddenDangerFeignApi;
    private final Converter converter;
    private final RemoteProcessFeignApi processFeignApi;
    private final AuthorityUtil authorityUtil;
    private final DozerUtil dozerUtil;

    /**
     * 质量检查新增
     */
    @ApiOperation(value = "质量检查新增", nickname = "质量检查新增")
    @PostMapping(value = "/saveQualityCheck")
    ResponseData<QualityCheckResponse> saveQualityCheck(@Validated @RequestBody SaveQualityCheckRequset saveQualityCheckRequset) {
        return remoteQualityCheckFeignApi.saveQualityCheck(saveQualityCheckRequset);
    }

    /**
     * 质量检查删除
     */
    @ApiOperation(value = "质量检查删除", nickname = "质量检查删除")
    @PostMapping(value = "/delQualityCheck")
    ResponseData<Boolean> delQualityCheck(@Validated @RequestBody DelQualityCheckRequest delQualityCheckRequest) {
        return remoteQualityCheckFeignApi.delQualityCheck(delQualityCheckRequest);
    }

    /**
     * 质量检查分页查询
     */
    @ApiOperation(value = "质量检查分页查询", nickname = "质量检查分页查询")
    @PostMapping(value = "/queryQualityCheckByPage")
    ResponseData<PaginationData<QualityCheckResponse>> queryQualityCheckByPage(@Validated @RequestBody QueryQualityCheckPageRequest queryQualityCheckPageRequest) {
        return remoteQualityCheckFeignApi.queryQualityCheckByPage(queryQualityCheckPageRequest);
    }

    /**
     * 质量检查详情查询
     */
    @ApiOperation(value = "质量检查详情查询", nickname = "质量检查详情查询")
    @PostMapping(value = "/queryQualityCheckDetail")
    ResponseData<QualityCheckDeatilAndRecordResponse> queryQualityCheckDetail(@Validated @RequestBody QueryQualityCheckDeatilRequest queryQualityCheckDeatilRequest) {
        ResponseData<QualityCheckDeatilResponse> qualityCheckDeatilResponseResponseData = remoteQualityCheckFeignApi.queryQualityCheckDetail(queryQualityCheckDeatilRequest);
        List<QualityCheckRecordResponse> qualityCheckRecordResponseList = new ArrayList<>();
        if (qualityCheckDeatilResponseResponseData.isSuccess()) {
            QualityCheckDeatilResponse qualityCheckDeatilResponse = qualityCheckDeatilResponseResponseData.getData();
            ResponseData<List<ProcessTaskResponse>> listResponseData = processFeignApi.getProcessTaskList(ProcessTaskListRequest.builder()
                    .businessCode(String.valueOf(qualityCheckDeatilResponse.getQualityCheck().getId()))
                    .businessType("QUALITY_CHECK")
                    .processDefinitionKey("PROCESS_QUALITY_CHECK")
                    .build());


            List<ProcessTaskResponse> processTaskResponses = listResponseData.getData();
            for (ProcessTaskResponse processTaskResponse : processTaskResponses) {
                if (null != processTaskResponse.getEndTime()) {
                    QualityCheckRecordResponse qualityCheckRecordResponse = new QualityCheckRecordResponse();
                    Long ownerId = null;
                    String ownername = "";
                    String job = "";
                    String result = "";
                    if (null != processTaskResponse.getOwner()) {
                        ownerId = processTaskResponse.getOwner().getId();
                        ownername = processTaskResponse.getOwner().getName();
                    }
                    Map<String, String> variables = processTaskResponse.getVariables();
                    for (String name : variables.keySet()) {
                        if ("PERSONJOB".equals(name)) {
                            job = variables.get(name);
                        }
                        if ("METHOD".equals(name)) {
                            result = variables.get(name);
                        }
                    }
                    qualityCheckRecordResponse.setReviewResult(result);
                    qualityCheckRecordResponse.setPersonResponse(new PersonResponse(ownerId, ownername, job));
                    qualityCheckRecordResponse.setComments(processTaskResponse.getComments());
                    qualityCheckRecordResponse.setFileResponse(processTaskResponse.getFiles());
                    qualityCheckRecordResponse.setId(processTaskResponse.getId());
                    qualityCheckRecordResponse.setTaskDefinitionKey(processTaskResponse.getTaskDefinitionKey());
                    qualityCheckRecordResponse.setName(processTaskResponse.getName());
                    qualityCheckRecordResponse.setStartTime(processTaskResponse.getStartTime());
                    qualityCheckRecordResponse.setEndTime(processTaskResponse.getEndTime());
                    qualityCheckRecordResponseList.add(qualityCheckRecordResponse);
                }
            }
        }

        return new ResponseData<>().success(QualityCheckDeatilAndRecordResponse.builder().qualityCheckDeatilResponse(qualityCheckDeatilResponseResponseData.getData()).qualityCheckRecordResponseList(qualityCheckRecordResponseList).build());
    }


    /**
     * 质量检查确认
     */
    @ApiOperation(value = "质量检查确认", nickname = "质量检查确认")
    @PostMapping(value = "/qualityCheckConfirmation")
    ResponseData<Boolean> qualityCheckConfirmation(@Validated @RequestBody QualityCheckConfirmationRequest qualityCheckConfirmationRequest) throws IOException {
        return remoteQualityCheckFeignApi.qualityCheckConfirmation(qualityCheckConfirmationRequest);
    }

    /**
     * 质量检查回复
     */
    @ApiOperation(value = "质量检查回复", nickname = "质量检查回复")
    @PostMapping(value = "/replyQualityCheck")
    ResponseData<ReplyQualityCheckResponse> replyQualityCheck(@Validated @RequestBody ReplyQualityCheckRequest replyQualityCheckRequest) {
        return remoteQualityCheckFeignApi.replyQualityCheck(replyQualityCheckRequest);
    }

    /**
     * 记录人修改整改单评价及建议
     */
    @ApiOperation(value = "记录人修改整改单评价及建议", nickname = "记录人修改整改单评价及建议")
    @PostMapping(value = "/noteTakerUpdateOrder")
    ResponseData<Boolean> noteTakerUpdateOrder(@Validated @RequestBody UpdateOrderRequest updateOrderRequest) {
        return remoteQualityCheckFeignApi.noteTakerUpdateOrder(updateOrderRequest);
    }

    /**
     * 修改记录
     * */
    @ApiOperation(value = "记录人修改整改单评价及建议(不涉及流程引擎)",nickname = "记录人修改整改单评价及建议(不涉及流程引擎)")
    @PostMapping("/noteTakerUpdateOrder/withoutActivity")
    ResponseData<Boolean> noteTakerUpdateOrderWithoutActivity(@Validated @RequestBody UpdateOrderRequest updateOrderRequest){
        return remoteQualityCheckFeignApi.noteTakerUpdateOrderWithoutActivity(updateOrderRequest);
    }

    @ApiOperation(value = "可关联隐患列表查询", nickname = "关联隐患列表查询")
    @PostMapping(value = "/queryAvailableHiddenDangerList")
    ResponseData<PaginationData<SfcOrQltHiddenDangerResponse>> queryAvailableHiddenDangerList(@Validated @RequestBody AvailableHiddenDangerRequest availableHiddenDangerRequest) {
        if (ConstantField.HiddenDangerSourceEnum.QLT.name().equals(availableHiddenDangerRequest.getHiddenDangerSource())) {
            QueryQualityHiddenDangerPageRequest queryQualityHiddenDangerPageRequest = converter.availableHiddenDangerRequestToQueryQualityHiddenDangerPageRequest(availableHiddenDangerRequest);
            queryQualityHiddenDangerPageRequest.setAvailable(true);
            ResponseData<PaginationData<QualityHiddenDangerResponse>> qltPage = remoteQualityHiddenDangerFeignApi.queryQualityHiddenDangerPage(queryQualityHiddenDangerPageRequest);
            return new ResponseData<>().success(converter.qualityHiddenDangerResponseToSfcOrQltHiddenDangerResponse(qltPage.getData()));
        } else if (ConstantField.HiddenDangerSourceEnum.SFC.name().equals(availableHiddenDangerRequest.getHiddenDangerSource())) {
            QueryHiddenDangerByCheckRequest queryHiddenDangerByCheckRequest = converter.availableHiddenDangerRequestToQueryHiddenDangerByCheckRequest(availableHiddenDangerRequest);
            queryHiddenDangerByCheckRequest.setAvailable(true);
            ResponseData<PaginationData<HiddenDangerResponse>> responseData = remoteHiddenDangerFeignApi.queryHiddenDangerListByCheck(queryHiddenDangerByCheckRequest);
            return new ResponseData<>().success(converter.hiddenDangerResponseToSfcOrQltHiddenDangerResponse(responseData.getData()));
        } else {
            return null;
        }
    }

    @ApiOperation(value = "质量检查模块单个隐患查询（兼容字段）", nickname = "质量检查模块单个隐患查询（兼容字段）")
    @PostMapping(value = "/queryCheckHiddenDangerByOne")
    ResponseData<SfcOrQltHiddenDangerResponse> queryCheckHiddenDangerByOne(@Validated @RequestBody QueryCheckHiddenDangerByOneRequest queryCheckHiddenDangerByOneRequest) {
        SfcOrQltHiddenDangerResponse sfcOrQltHiddenDangerResponse = new SfcOrQltHiddenDangerResponse();
        if (ConstantField.HiddenDangerSourceEnum.QLT.name().equals(queryCheckHiddenDangerByOneRequest.getHiddenDangerSource())) {
            sfcOrQltHiddenDangerResponse = queryQualityHiddenDangerByOne(queryCheckHiddenDangerByOneRequest.getHiddenDangerId());
        }
        if (ConstantField.HiddenDangerSourceEnum.SFC.name().equals(queryCheckHiddenDangerByOneRequest.getHiddenDangerSource())) {
            sfcOrQltHiddenDangerResponse = querySafetyHiddenDangerByOne(queryCheckHiddenDangerByOneRequest.getHiddenDangerId());
        }
        return new ResponseData<>().success(sfcOrQltHiddenDangerResponse);
    }


    private SfcOrQltHiddenDangerResponse querySafetyHiddenDangerByOne(Long hiddenDangerId) {
        ResponseData<HiddenDangerDetailResponse> responseResponseData = remoteHiddenDangerFeignApi.searchHiddenDangerDetail(hiddenDangerId);

        HiddenDangerDetailResponse response = responseResponseData.getData();
        HiddenDangerOperateDetailResponse hiddenDangerOperateDetailResponse = dozerUtil.convertor(response, HiddenDangerOperateDetailResponse.class);

        Map<String, Map<String, Object>> detailInfo = response.getDetailInfo();
        List<HiddenDangerOperateResponse> hiddenDangerOperateResponses = new ArrayList<>();
        for (String date : detailInfo.keySet()) {
            HiddenDangerOperateResponse operateResponse = new HiddenDangerOperateResponse();
            if (date.contains(" ")) {
                operateResponse.setOperateTime(LocalDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            } else {
                operateResponse.setOperateTime(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
            }
            Map<String, Object> objectMap = detailInfo.get(date);
            for (String name : objectMap.keySet()) {
                operateResponse.setOperateName(name);
                operateResponse.setOperateInfo(objectMap.get(name));
            }
            hiddenDangerOperateResponses.add(operateResponse);
        }

        List<HiddenDangerOperateResponse> hiddenDangerOperateResponsesSort = hiddenDangerOperateResponses.stream().sorted(Comparator.comparing(HiddenDangerOperateResponse::getOperateTime)).collect(Collectors.toList());

        hiddenDangerOperateDetailResponse.setOperateResponses(hiddenDangerOperateResponsesSort);
        return converter.hiddenDangerOperateDetailResponseToSfcOrQltHiddenDangerResponse(hiddenDangerOperateDetailResponse);

    }

    private SfcOrQltHiddenDangerResponse queryQualityHiddenDangerByOne(Long hiddenDangerId) {
        ResponseData<QualityHiddenDangerResponse> responseResponseData = remoteQualityHiddenDangerFeignApi.queryQualityHiddenDangerByOne(QueryQualityHiddenDangerByOneRequest.builder().id(hiddenDangerId).build());
        SfcOrQltHiddenDangerResponse sfcOrQltHiddenDangerResponse = new SfcOrQltHiddenDangerResponse();

        if (responseResponseData.isSuccess()) {
            sfcOrQltHiddenDangerResponse = converter.qualityHiddenDangerResponseToSfcOrQltHiddenDangerResponse(responseResponseData.getData());

            com.smedi.ismedi.web.starter.common.ResponseData<List<ProcessTaskResponse>> listResponseData = processFeignApi.getProcessTaskList(ProcessTaskListRequest.builder()
                    .businessCode(String.valueOf(hiddenDangerId))
                    .businessType("QLT_HIDDEN_DANGER")
                    .processDefinitionKey("PROCESS_QLT_HIDDENDANGER_RECTIFICATION")
                    .build());

            List<RectificationRecordResponse> rectificationRecords = new ArrayList<>();
            if (listResponseData.isSuccess() && CollectionUtil.isNotEmpty(listResponseData.getData())) {
                List<ProcessTaskResponse> processTaskResponses = listResponseData.getData();
                for (ProcessTaskResponse processTaskResponse : processTaskResponses) {
                    if (null != processTaskResponse.getEndTime() &&
                            ("ACTIVITY_HIDDENDANGER_RECTIFICATION".equals(processTaskResponse.getTaskDefinitionKey())
                                    || "ACTIVITY_HIDDENDANGER_REVIEW".equals(processTaskResponse.getTaskDefinitionKey()))) {
                        RectificationRecordResponse rectificationRecord = new RectificationRecordResponse();
                        Long ownerId = null;
                        String ownername = "";
                        String job = "";
                        String result = "";
                        if (null != processTaskResponse.getOwner()) {
                            ownerId = processTaskResponse.getOwner().getId();
                            ownername = processTaskResponse.getOwner().getName();
                        }
                        Map<String, String> variables = processTaskResponse.getVariables();
                        for (String name : variables.keySet()) {
                            if ("PERSONJOB".equals(name)) {
                                job = variables.get(name);
                            }
                            if ("METHOD".equals(name)) {
                                result = variables.get(name);
                            }
                        }
                        rectificationRecord.setId(processTaskResponse.getId());
                        rectificationRecord.setTaskDefinitionKey(processTaskResponse.getTaskDefinitionKey());
                        rectificationRecord.setName(processTaskResponse.getName());
                        rectificationRecord.setStartTime(processTaskResponse.getStartTime());
                        rectificationRecord.setEndTime(processTaskResponse.getEndTime());
                        rectificationRecord.setReviewResult(result);
                        rectificationRecord.setPersonResponse(new PersonResponse(ownerId, ownername, job));
                        rectificationRecord.setComments(processTaskResponse.getComments());
                        rectificationRecord.setFileResponse(processTaskResponse.getFiles());
                        rectificationRecords.add(rectificationRecord);
                    }
                }
            }
            sfcOrQltHiddenDangerResponse.setRectificationRecordResponses(rectificationRecords);

        }

        return sfcOrQltHiddenDangerResponse;
    }


}
